#pragma once
#include <iostream>
#include <functional>
#include <boost/asio.hpp>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <iomanip>


class SerialPort
{
public:
    using DataCallback = std::function<void(const std::string& data)>;
    using ErrorCallback = std::function<void(const std::string& errorMsg)>;

    SerialPort(const std::string& port_name, int baud_rate = 9600,
        int parity = 0, int databit = 8, int stopbit = 1);
    ~SerialPort();

    SerialPort(const SerialPort&) = delete;
    SerialPort& operator=(const SerialPort&) = delete;

    bool IsOpen() const;
    bool init_port(const std::string& port_name, int baud_rate,
        int parity, int databit, int stopbit);

    void Close();

    void write_to_serial(const std::string& data, bool hex);
    void StartReading(DataCallback dataCallback, ErrorCallback errorCallback = nullptr);
    void StopReading();

    void ReadOnceAsync(DataCallback dataCallback, ErrorCallback errorCallback = nullptr);

    bool reopen_port(int new_baud_rate);


    std::string BinaryToHexString(const std::vector<unsigned char>& data) {
        std::stringstream ss;
        ss << std::hex << std::uppercase;
        for (size_t i = 0; i < data.size(); ++i) {
            ss << "0x" << std::setw(2) << std::setfill('0') << static_cast<int>(data[i]);
            if (i != data.size() - 1) {
                ss << " ";
            }
        }
        return ss.str();
    }

private:
    void handle_read(const boost::system::error_code& ec, std::size_t bytes_transferred);
    void handle_write(const boost::system::error_code& ec, std::size_t bytes_transferred);
    void process_received_data(const std::string& data);
    bool clearBuffer();

    boost::asio::io_context m_ios;
    std::unique_ptr<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> m_work;
    std::thread m_ioThread;// IO 线程
    std::unique_ptr<boost::asio::serial_port> pSerialPort;
    std::string m_port;
    int m_baudRate;
    int m_parity;
    int m_dataBits;
    int m_stopBits;
    boost::system::error_code m_ec;

    char m_readBuffer[1024];
    std::string m_partialData;
    DataCallback m_dataCallback;
    ErrorCallback m_errorCallback;
    std::atomic<bool> m_isReading{ false };
    std::atomic<bool> m_isStopping{ false };

    bool m_paramsValid = false;

    // 发送缓冲区（支持异步写入）
    std::queue<std::vector<unsigned char>> m_sendQueue;
    std::mutex m_sendMutex;
    bool m_isSending = false;

    std::atomic<bool> m_isReadingAsync{ false };  // 标记是否正在执行单次异步读取
};